package com.ruoyi.charge.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.charge.auth.entity.ApiToken;
import com.ruoyi.charge.auth.entity.req.RegisterReq;
import com.ruoyi.charge.auth.entity.res.AccessTokenResponse;
import com.ruoyi.charge.auth.entity.res.RefreshTokenResponse;
import com.ruoyi.charge.domain.WxUser;
import com.ruoyi.charge.mapper.WxUserMapper;
import com.ruoyi.charge.service.IUserService;
import com.ruoyi.charge.auth.service.LoginTokenService;
import com.ruoyi.charge.domain.Agent;
import com.ruoyi.charge.domain.Store;
import com.ruoyi.charge.mapper.AgentMapper;
import com.ruoyi.charge.mapper.StoreMapper;
import com.ruoyi.charge.vo.WxUserVo;
import com.ruoyi.common.enums.DeletedStatus;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class IUserServiceImpl implements IUserService {

    private static String appid = "wx40bd649374e36f03";
    private static String appsecret = "fec157be241fc0a68e5fe7aaf1119b0b";

    @Autowired
    private LoginTokenService loginTokenService;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private AgentMapper agentMapper;
    @Autowired
    private WxUserMapper wxUserMapper;


    @Override
    public Boolean register(RegisterReq req) {
        String phone = req.getPhone();
        Integer type = req.getType();
        String password = SecurityUtils.encryptPassword(req.getPassword());
        if (type == 0) {
            //店铺注册
            Store store = storeMapper.selectOne(
                    new LambdaQueryWrapper<Store>()
                            .eq(Store::getNumber, phone)
                            .eq(Store::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if (store != null) {
                return false;
            }
            Store insert = new Store();
            insert.setNumber(phone);
            insert.setStoreName(phone);
            insert.setPhone(phone);
            insert.setPassword(password);
            storeMapper.insert(insert);
            return true;
        } else if (type == 1) {
            //代理商注册
            Agent agent = agentMapper.selectOne(
                    new LambdaQueryWrapper<Agent>()
                            .eq(Agent::getAgentNumber, phone)
                            .eq(Agent::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if (agent != null) {
                return false;
            }
            Agent insert = new Agent();
            insert.setAgentNumber(phone);
            insert.setAgentName(phone);
            insert.setPassword(password);
            insert.setPhone(phone);
            agentMapper.insert(insert);
            return true;
        } else {
            throw new CustomException("type 类型错误！");
        }
    }

    @Override
    public AccessTokenResponse getAccessTokenByAccount(String phone, String password) {

//        password = SecurityUtils.encryptPassword(password);
        Store store = storeMapper.selectOne(
                new LambdaQueryWrapper<Store>()
                        .eq(Store::getNumber, phone)
                        .eq(Store::getDeleted, DeletedStatus.VALID.getCode())
                        .last("limit 1")
        );
        if (store == null) {
            Agent agent = agentMapper.selectOne(
                    new LambdaQueryWrapper<Agent>()
                            .eq(Agent::getAgentNumber, phone)
                            .eq(Agent::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if (agent == null) {
                throw new CustomException("手机号不存在！");
            }
            if (!SecurityUtils.matchesPassword(password, agent.getPassword())) {
                throw new CustomException("密码不正确！");
            }
            //获取token
            ApiToken token = loginTokenService.creatToken(agent.getAgentId(), 1);
            AccessTokenResponse resp = AccessTokenResponse.builder()
                    .accessToken(token.getAccessToken())
                    .expiresIn(token.getAccessTokenExpireTime().getTime() / 1000 - System.currentTimeMillis() / 1000)
                    .refreshToken(token.getRefreshToken())
                    .type(1)
                    .agent(agent)
                    .build();
            return resp;
        }
        if (!SecurityUtils.matchesPassword(password, store.getPassword())) {
            throw new CustomException("密码不正确！");
        }
        //获取token
        ApiToken token = loginTokenService.creatToken(store.getStoreId(), 0);
        AccessTokenResponse resp = AccessTokenResponse.builder()
                .accessToken(token.getAccessToken())
                .expiresIn(token.getAccessTokenExpireTime().getTime() / 1000 - System.currentTimeMillis() / 1000)
                .refreshToken(token.getRefreshToken())
                .type(0)
                .store(store)
                .build();
        return resp;

    }

    @Override
    public RefreshTokenResponse refreshAccessToken(Long userId, String refreshToken, Integer type) {
        if (type == 0) {
            Store store = storeMapper.selectOne(
                    new LambdaQueryWrapper<Store>()
                            .eq(Store::getStoreId, userId)
                            .eq(Store::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if (store == null) {
                throw new CustomException("用户Id不存在！");
            }
            ApiToken token = loginTokenService.refreshToken(userId, refreshToken, type);
            RefreshTokenResponse resp = RefreshTokenResponse.builder()
                    .accessToken(token.getAccessToken())
                    .expiresIn(token.getAccessTokenExpireTime().getTime() / 1000 - System.currentTimeMillis() / 1000)
                    .refreshToken(token.getRefreshToken())
                    .build();
            return resp;
        } else if (type == 1) {
            Agent agent = agentMapper.selectOne(
                    new LambdaQueryWrapper<Agent>()
                            .eq(Agent::getAgentId, userId)
                            .eq(Agent::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if (agent == null) {
                throw new CustomException("用户Id不存在！");
            }
            ApiToken token = loginTokenService.refreshToken(userId, refreshToken, type);
            RefreshTokenResponse resp = RefreshTokenResponse.builder()
                    .accessToken(token.getAccessToken())
                    .expiresIn(token.getAccessTokenExpireTime().getTime() / 1000 - System.currentTimeMillis() / 1000)
                    .refreshToken(token.getRefreshToken())
                    .build();
            return resp;
        } else {
            throw new CustomException("type 错误！");
        }
    }

    @Override
    public String getWxUserLoginInfo(String code) {
        String openid = "";
        String param = "appid=" + appid + "&secret=" + appsecret + "&js_code=" + code + "&grant_type=authorization_code";
        String result = HttpUtils.sendGet("https://api.weixin.qq.com/sns/jscode2session", param);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (jsonObject != null && jsonObject.get("openid") != null) {
            openid = jsonObject.getString("openid");
            WxUser wxUser = wxUserMapper.selectOne(
                    new LambdaQueryWrapper<WxUser>().eq(WxUser::getOpenid, openid)
                            .eq(WxUser::getDeleted, DeletedStatus.VALID.getCode())
                            .last("limit 1")
            );
            if(wxUser == null){
                WxUser add = new WxUser();
                add.setOpenid(openid);
                wxUserMapper.insert(add);
            }
        }
        return openid;
    }
}
